import React from 'react';
import { connect } from 'react-redux';
import { Input, InputNumber, message, Popover, Spin, Tag, Row, Col, Button} from 'antd';
import Chooser from 'components/chooser';
import 'styles/my-account/expense-apportion.scss';
import chooserData from 'share/chooserData';
import { deepFullCopy, messages, queryCurrencyPrecision, } from 'share/common';
import config from 'config';
import Condition from 'components/condition';
import ResizeTable from "components/resize-table";
import confirmSumptionService from './confirm-consumption.service'

const InputGroup = Input.Group;
const If = Condition.If;

class ApportionFrame extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      heights: [],
      costCenterOID: '00000000-0000-0000-0000-000000000000',
      columns: [
        {
          title:  messages('common.sequence')/*序号*/,
          dataIndex: 'index',
          width: 72,
          render: (text, record, index) => <span>{index + 1}</span>
        },
        {
          title: messages('expense-1.key1')/*分摊项*/,
          dataIndex: 'costCenterRender',
          width: 300,
          render: (text, record, index) => this.renderColumns(record, 'costCenterRender', index),
        },
        {
          title: messages('expense-1.key198')/*分摊金额*/,
          dataIndex: 'amount',
          width: 100,
          render: (text, record, index) => this.renderColumns(record, 'amount', index)
        }, {
          title: messages('expense-1.key199')/*分摊比例*/,
          dataIndex: 'proportion',
          width: 100,
          render: (text, record, index) => this.renderColumns(record, 'proportion', index)
        }, {
          title: messages('expense-1.key200')/*相关人*/,
          dataIndex: 'personName',
          width: 100,
          render: (text, record, index) => this.renderColumns(record, 'personName', index)
        }],
      currencyCode: props.currencyCode,
      apportionSettings: []
    };
  }

  componentWillMount() {
    if ('value' in this.props) {
      const value = this.props.value;
      let columns = this.state.columns;
      if(!this.props.disabled && !columns.filter(i => i.dataIndex === 'operate').length) {
        columns.push({
          title: messages('common.operation')/*操作*/,
          dataIndex: 'operate',
          width: 100,
          render: (text, record, index) => this.renderColumns(record, 'operate', index)
        });
      }
      this.setState({ value, columns });
    }
    this.getApportionSetting();
  }

  componentWillReceiveProps(nextProps) {
    if ('value' in nextProps) {
      const value = nextProps.value;
      this.setState({ value });
    }
  }

  onChange = currentValue => {
    const { value } = this.state;
    const onChange = this.props.onChange;
    onChange && onChange(currentValue || value);
  };

  getApportionSetting = () => {
    confirmSumptionService.getApportionSetting(this.props.tenant.id).then(res => {
      this.setState({ apportionSettings: res.data.costCenters || []});
    })
  };

  /*获取币种精度*/
  getCurrencyPrecision = (currencyCode = this.props.currencyCode) => {
    return queryCurrencyPrecision(currencyCode);
  };


  handleChangeCostCenter = (result, index, costCenterIndex) => {
    if (result) {
      if (result.length === 0) {
        result[0] = {};
      }
      let { value } = this.state;
      let costCenterItems = value[index].costCenterItems[costCenterIndex];
      if (costCenterItems && (costCenterItems.costCenterItemOID !== result[0].costCenterItemOID || costCenterItems.costCenterItemOID !== result[0].departmentOid  )) {
        let name = result[0].name;
        costCenterItems.costCenterItemId = result[0].id || result[0].costCenterItemId;
        costCenterItems.costCenterItemOID = result[0].costCenterItemOID;
        costCenterItems.costCenterItemName = name;
        costCenterItems.name = name;
        costCenterItems.itemCode = result[0].custDeptNumber || result[0].code;
        value[index].costCenterItems[costCenterIndex] = costCenterItems;
        this.setState({ value });
        this.onChange(value);
      }
    }
  };

  handleChangeAmount = (result, index) => {
    if (typeof result === 'number' && !isNaN(result) && result !== 0) {
      let { value } = this.state;
      const { amount } = this.props;
      let currencyPrecision = this.getCurrencyPrecision();
      value[index].apportionAmount = Number((result).toFixed(currencyPrecision));
      value[index].proportion = (result / amount) > 1 ? 1 : result / amount;
      this.setState({ value });
      this.onChange(value);
    }
  };

  handleChangeProportion = (result, index) => {
    if (typeof result === 'number' && !isNaN(result)) {
      let { value } = this.state;
      const { amount } = this.props;
      let currencyPrecision = this.getCurrencyPrecision();
      value[index].proportion = result / 100;
      value[index].apportionAmount = Number((result / 100 * amount).toFixed(currencyPrecision));
      this.setState({ value });
      this.onChange(value);
    }
  };

  handleChangePerson = (result, index) => {
    if (result) {
      let { value } = this.state;
      value[index].userId = result[0].id;
      value[index].userName = result[0].fullName;
      this.setState({ value });
      this.onChange(value);
    }
  };

  renderColumns = (record, attr, index) => {
    const { disabled, loginUser: { fullName, id } } = this.props;
    let currencyPrecision = this.getCurrencyPrecision();
    switch (attr) {
      case 'costCenterRender':
        return (
          <div className="department">
            {record.costCenterItems.map((costCenterItem, costCenterItemIndex) => {
              return (
                <InputGroup key={costCenterItemIndex} className="apportion-item-group">
                  <Popover content={costCenterItem.costCenterName} placement="topLeft">
                    <Input
                      defaultValue={`${costCenterItem.costCenterName}:`}
                      className="apportion-item-group-title"
                      disabled
                    />
                  </Popover>
                  {this.departmentCostCenterItem(record, index, costCenterItem, costCenterItemIndex)}
                </InputGroup>
              );
            })}
          </div>
        );
      case 'amount':
        return disabled ? this.filterMoney(record.apportionAmount, currencyPrecision)
          : (
            <InputNumber
              className="apportion-amount"
              onChange={(value) => this.handleChangeAmount(value, index)}
              value={record.apportionAmount}
              precision={currencyPrecision}
              step={currencyPrecision ? 1 / Math.pow(10, currencyPrecision) : 1}
              formatter={value => (typeof value === 'number' && !isNaN(value)) ? Number(value.toFixed(currencyPrecision)) : value}
            />);
      case 'proportion':
        return disabled ? `${(record.proportion * 100).toFixed(2)}%`
          : (
            <InputNumber
              min={0}
              className="expense-proportion-symbol"
              precision={2}
              step={0.01}
              max={100}
              onChange={(value) => this.handleChangeProportion(value, index)}
              value={record.proportion * 100}
              formatter={value => (typeof value === 'number' && !isNaN(value)) ? Number(value.toFixed(2)) : value}
            />);
      case 'personName':
        let user = record && record.userId ? [{
          fullName: record.userName,
          id: record.userId
        }] : null;
        return disabled ? user[0].fullName : this.renderPersonName(user, index);
      case 'operate':
        return (
          <div className="apportion-operate">
            <a onClick={() => this.handleCopyApportionFrame(record)}
               style={{marginRight: 10}}>
              {messages('common.copy')/*复制*/}
            </a>
            <If value={this.handleIsShowDelete()}>
              <a style={{ marginRight: 10 }} onClick={() => this.handleRemoveApportionFrame(index)}>
                {messages('common.delete')/*删除*/}
              </a>
            </If>
          </div>
        );
      default:
        return null;
    }
  };

  renderPersonName = (user, index) => {
    let listExtraParams = { roleType: 'TENANT' };
    return (
      <Chooser
        type='user'
        valueKey="id"
        labelKey="fullName"
        single
        value={user}
        showClear={false}
        listExtraParams={listExtraParams}
        onChange={value => this.handleChangePerson(value, index)}
      />
    )
  };

  departmentCostCenterItem(record, index, constraint, costCenterIndex) {
    const { disabled, loginUser } = this.props;

    let chooserItem = JSON.parse(JSON.stringify(chooserData['expense_cost_center_item']));
    chooserItem.key = 'costCenterItemOID';
    chooserItem.title = constraint.costCenterName;
    chooserItem.searchForm = [{
      type: 'input',
      id: 'keyword',
      label: `${constraint.costCenterName}${messages('expense-1.key203')/*代码*/}/${messages('expense-1.key204')/*名称*/}`
    }];
    chooserItem.columns = [{
      title: `${constraint.costCenterName}${messages('expense-1.key203')/*代码*/}`,
      dataIndex: 'code'
    }, {
      title: `${constraint.costCenterName}${messages('expense-1.key204')/*名称*/}`,
      dataIndex: 'name'
    }];
    chooserItem.url = `${config.baseUrl}/api/my/cost/center/items/${constraint.costCenterOID}`;

    let listExtraParams = {
      applicantOID: loginUser.userOID,
    };
    let value = {};
    record.costCenterItems.map(item => {
      if (item.costCenterOID === constraint.costCenterOID) {
        value = item;
      }
    });
    value.name = value.costCenterItemName;
    const name = value.costCenterItemName;
    let nameHtml = <Popover placement="topLeft" content={name || ''}>{name || ''}</Popover>;
    return (
      disabled ?
        <Input prefix={nameHtml} style={{ borderLeft: '0px', width: '70%' }} disabled/>
        : (
          <Chooser
            selectorItem={chooserItem}
            valueKey="costCenterItemOID"
            labelKey="name"
            single
            showClear
            itemMap
            listExtraParams={listExtraParams}
            onChange={costCenterItem => this.handleChangeCostCenter(costCenterItem, index, costCenterIndex)}
            value={value.costCenterItemOID ? [value] : []}
          />
        )
    );
  }

  handleRemoveApportionFrame = (index) => {
    let { value } = this.state;
    if (index === 0 && value.length > 1) {
      value[1].defaultApportion = true;
      this.setState({ defaultApportionFrame: value[1] });
    }
    value.splice(index, 1);
    this.setState({ value });
    this.onChange(value);
  };

  handleIsShowDelete = () => this.state.value.length !== 1;

  handleCopyApportionFrame = (record) => {
    let { value } = this.state;
    let target = JSON.parse(JSON.stringify(record));
    target.apportionAmount = 0;
    target.proportion = 0;
    target.apportionmentOID = null;
    target.defaultApportion = false;
    target.id = null;
    value.push(target);
    this.setState({ value });
    this.onChange(value);
  };

  handleApportionSettings = () => {
    const { value, apportionSettings } = this.state;
    return value && value[0] ?
      value[0].costCenterItems.map(i => {i.costCenterItemOID = null; return i;}) :
      apportionSettings.map(i => {i.costCenterName = i.name; return i;})
  };

  handleAddApportion = () => {
    const { value } = this.state;
    const { loginUser: { fullName, id }} = this.props;
    let dataSource = deepFullCopy(value);
    console.log(value);
    dataSource.push({
      costCenterItems: this.handleApportionSettings(),
      apportionAmount: 0,
      proportion: 0,
      userId: id,
      userName: fullName,
    });
    this.setState({ value: dataSource }, this.onChange)
  };

  handleSpreadApportion = () => {
    const { value } = this.state;
    const { amount } = this.props;

    if(!value || !value.length) {
      message.error(messages('expense-16.key427')/*请先新建分摊*/);
      return;
    }
    let dataSource = [];
    let length = value.length;
    value.map(i => {
      dataSource.push({
        costCenterItems: i.costCenterItems,
        userId: i.userId,
        userName: i.userName,
        apportionAmount: this._precisionOverflow(Number(amount) / length),
        proportion: Math.round((1 / length) * 10000) / 100,
      })
    });
    dataSource[length - 1].proportion = 100 - dataSource.reduce((total, i, index) => total + (index < length - 1 ? i.proportion : 0), 0);
    dataSource[length - 1].apportionAmount = Number(amount) - dataSource.reduce((total, i, index) => total + (index < length - 1 ? Number(i.apportionAmount) : 0), 0);
    dataSource = dataSource.map(i => {
      i.proportion = i.proportion / 100;
      i.proportion = Number(i.proportion.toFixed(4));
      i.apportionAmount = this._precisionOverflow(i.apportionAmount);
      return i
    });
    this.setState({ value: dataSource }, this.onChange);
  };

  _precisionOverflow = (amount, precision) => {
    let _precision = precision || queryCurrencyPrecision(this.props.currencyCode);
    return Number(Number(amount).toFixed(_precision))
  };

  render() {
    const { columns, value } = this.state;
    const { amount, disabled } = this.props;
    return (
      <div className="apportion-frame">
        <ResizeTable
          showUtils
          tableName="apportion-frame-table"
          columns={columns}
          dataSource={value}
          bordered
          scroll={{ x: 450 }}
          pagination={false}
        />
        {!disabled && amount ? (
          <Row style={{marginTop: 12}} gutter={8}>
            <Col span={12} >
              <Button type="dashed" style={{width: '100%', height: 32}} onClick={this.handleAddApportion}>{messages('expense-16.key428')/*新建分摊*/}</Button>
            </Col>
            <Col span={12}>
              <Button type="dashed" style={{width: '100%', height: 32}} onClick={this.handleSpreadApportion}>{messages('expense-1.key10')/*一键均摊*/}</Button>
            </Col>
          </Row>
        ) : null}
      </div>
    );
  }
}

ApportionFrame.propTypes = {
  value: React.PropTypes.array,
  amount: React.PropTypes.number,
};

ApportionFrame.defaultProps = {
  costCenterItemsApportion: []
};

function mapStateToProps(state) {
  return {
    loginUser: state.login.loginUser,
    tenant: state.login.tenant,
  };
}

export default connect(mapStateToProps)(ApportionFrame);
